#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <string.h>
#include "ArbreBinaire.h"
#include "SDLDraw.h"

#define M_PI 3.14159265358979323846
#define SGN(x) ((x) > 0 ? 1 : ((x) == 0 ? 0 : (-1)))

void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination) { 
	SDL_Rect offset; 

	offset.x = x; 
	offset.y = y;

	SDL_BlitSurface(source, NULL, destination, &offset); 

    SDL_FreeSurface(source);
}

void clearScreen(SDL_Surface* surface)
{
    SDL_FillRect(surface, NULL, 0xfffffff);
}


void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    Uint8 *target_pixel = (Uint8 *)surface->pixels + y * surface->pitch + x * 4;
    *(Uint32 *)target_pixel = pixel;
}

void drawLine(SDL_Surface *surface, Uint32 x1, Uint32 y1, Uint32 x2, Uint32 y2, Uint32 color)
{
    int lg_delta, sh_delta, cycle, lg_step, sh_step;

    lg_delta = x2 - x1;
    sh_delta = y2 - y1;
    lg_step = SGN(lg_delta);
    lg_delta = abs(lg_delta);
    sh_step = SGN(sh_delta);
    sh_delta = abs(sh_delta);
    if (sh_delta < lg_delta) {
        cycle = lg_delta >> 1;
        while (x1 != x2) {
            setPixel(surface, x1, y1, color);
            cycle += sh_delta;
            if (cycle > lg_delta) {
                cycle -= lg_delta;
                y1 += sh_step;
            }
            x1 += lg_step;
        }
        setPixel(surface, x1, y1, color);
    }
    cycle = sh_delta >> 1;
    while (y1 != y2) {
        setPixel(surface, x1, y1, color);
        cycle += lg_delta;
        if (cycle > sh_delta) {
            cycle -= sh_delta;
            x1 += lg_step;
        }
        y1 += sh_step;
    }
    setPixel(surface, x1, y1, color);
}

void drawCircle(SDL_Surface *surface, int n_cx, int n_cy, int radius, Uint32 pixel)
{
    double error = (double)-radius;
    double x = (double)radius -0.5;
    double y = (double)0.5;
    double cx = n_cx - 0.5;
    double cy = n_cy - 0.5;
 
    while (x >= y)
    {
        setPixel(surface, (int)(cx + x), (int)(cy + y), pixel);
        setPixel(surface, (int)(cx + y), (int)(cy + x), pixel);
 
        if (x != 0)
        {
            setPixel(surface, (int)(cx - x), (int)(cy + y), pixel);
            setPixel(surface, (int)(cx + y), (int)(cy - x), pixel);
        }
 
        if (y != 0)
        {
            setPixel(surface, (int)(cx + x), (int)(cy - y), pixel);
            setPixel(surface, (int)(cx - y), (int)(cy + x), pixel);
        }
 
        if (x != 0 && y != 0)
        {
            setPixel(surface, (int)(cx - x), (int)(cy - y), pixel);
            setPixel(surface, (int)(cx - y), (int)(cy - x), pixel);
        }
 
        error += y;
        ++y;
        error += y;
 
        if (error >= 0)
        {
            --x;
            error -= x;
            error -= x;
        }
    }
}

void drawFlecheArbre(SDL_Surface* surface, int xArbre, int yArbre, int rayonArbre, int gauche, int bas) {
    int taillePointe = (30.0 / 100.0) * rayonArbre;
    int largeurPointe = taillePointe / 2;

    int xFleche;

    if (gauche)
        xFleche = xArbre - rayonArbre - taillePointe;
    else
        xFleche = xArbre + rayonArbre + taillePointe;

    int yFlecheOrigine;
    int yFlecheBasePointe;
    int yFlechePointe;

    if (bas) {
        yFlecheOrigine = yArbre - rayonArbre;
        yFlecheBasePointe = yArbre + rayonArbre - taillePointe;
        yFlechePointe = yArbre + rayonArbre;
    }
    else {
        yFlecheOrigine = yArbre + rayonArbre;
        yFlecheBasePointe = yArbre - rayonArbre + taillePointe;
        yFlechePointe = yArbre - rayonArbre;
    }

    drawLine(surface, xFleche, yFlecheOrigine, xFleche, yFlecheBasePointe, 0);
    drawLine(surface, xFleche - largeurPointe, yFlecheBasePointe, xFleche + largeurPointe, yFlecheBasePointe, 0); 
    drawLine(surface, xFleche - largeurPointe, yFlecheBasePointe, xFleche, yFlechePointe, 0);
    drawLine(surface, xFleche + largeurPointe, yFlecheBasePointe, xFleche, yFlechePointe, 0); 
}